#!/usr/bin/python
#
# Copyright 2011 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


"""Build Mimic."""


__author__ = 'jason.stredwick@gmail.com (Jason Stredwick)'


import os
import subprocess
import shutil


BUILD_ROOT = os.path.join('build_support', 'bite_build')


# Attempt to import BITE build files.
bite_build_imported = False
try:
  from build_support.bite_build import clean
  from build_support.bite_build import deps as DEPS
  from build_support.bite_build import extension as EXTENSION
  from build_support.bite_build import flags as FLAGS
  from build_support.bite_build import paths as PATHS
  from build_support.bite_build import rpf as RPF
  from build_support.bite_build import server as SERVER
  from build_support.bite_build import tools
  bite_build_imported = True
except ImportError:
  # On failure to import build files, download them.  This code should only
  # be called upon import failure, so no need to verify existence of the target
  # just download it again to ensure all parts are present.
  def DownloadBITEBuild():
    """Check that opensource BITE is installed and install if not."""
    print 'Opensource BITE build is not downloaded.  Downloading now ...'

    def GetExecutable(executable):
      """Derived from bite_build.tools.GetExecutable."""
      extensions = os.environ.get('PATHEXT', '').split(os.pathsep)
      paths = os.environ.get('PATH', '').split(os.pathsep)

      # Loop over every combination of path and file extension.
      for extension in extensions:
        for path in paths:
          full_path = os.path.join(path, '%s%s' % (executable, extension))
          if os.path.isfile(full_path) and os.access(full_path, os.X_OK):
            return full_path

      return None

    try:
      target = BUILD_ROOT
      url = 'https://code.google.com/p/bite-project.build'
      git = GetExecutable('git')
      if git is None:
        raise Exception

      process = subprocess.Popen([git, 'clone', url, target],
                                 stderr=subprocess.STDOUT,
                                 stdout=subprocess.PIPE)
      (out, _) = process.communicate()

      if process.returncode:
        raise Exception
      else:
        print '[SUCCESS] Download of BITE build complete.'
        print ''
    except Exception:
      print '[FAILED]  Could not download BITE build from %s.' % url
      print '  %s' % out
      print 'Build failed ... exiting.'
      exit()

  DownloadBITEBuild()


# If the build files failed to be imported then try again after download phase.
if not bite_build_imported:
  from build_support.bite_build import clean
  from build_support.bite_build import deps as DEPS
  from build_support.bite_build import extension as EXTENSION
  from build_support.bite_build import flags as FLAGS
  from build_support.bite_build import paths as PATHS
  from build_support.bite_build import rpf as RPF
  from build_support.bite_build import server as SERVER
  from build_support.bite_build import tools


from build_support import gen_firefox3_6
from build_support import ie7
from build_support import gen_ie7
from build_support import run_ie7


def Main():
  """The main entry point for the build system."""
  cmdline_flags = FLAGS.FLAGS
  flags_to_remove = [FLAGS.EXTENSION_ONLY, FLAGS.RPF, FLAGS.SERVER_ONLY]
  for flag in flags_to_remove:
    try:
      del cmdline_flags[flag]
    except:
      pass
  for flag in ie7.FLAGS:
    cmdline_flags[flag] = ie7.FLAGS[flag]
  args = FLAGS.Process(cmdline_flags)
  verbose = not args[FLAGS.QUIET]

  # Prioritized process of command line arguments
  if args[FLAGS.EXPUNGE]:
    clean_paths = clean.CLEAN_PATHS
    expunge_paths = clean.EXPUNGE_PATHS
    expunge_paths['build'] = BUILD_ROOT
    clean.RemovePaths(clean_paths.values() + expunge_paths.values())
    exit()
  elif args[FLAGS.CLEAN]:
    clean_paths = clean.CLEAN_PATHS
    clean.RemovePaths(clean_paths.values())
    exit()

  # Set up the directories that will be built into.
  output_paths = [PATHS.GENFILES_ROOT, PATHS.DEPS_ROOT]
  for path in output_paths:
    if not os.path.exists(path):
      os.mkdir(path)

  # Prepare initial tool and dependency lists.
  req_tools = tools.TOOLS
  bite_deps = DEPS.CreateDeps()

  # Verify required tools
  tools_to_remove = [tools.MERCURIAL, tools.SVN]
  for tool in tools_to_remove:
    try:
      del req_tools[tool]
    except:
      pass
  if not tools.Verify(req_tools, verbose):
    print 'Build failed ... exiting.'
    exit()
  if verbose:
    print ''

  # Verify and download dependencies
  git = tools.GetExecutable(tools.TOOLS[tools.GIT][tools.COMMAND])
  deps = {
    DEPS.CLOSURE_COMPILER: bite_deps[DEPS.CLOSURE_COMPILER],
    DEPS.CLOSURE_LIB: bite_deps[DEPS.CLOSURE_LIB],
    'bite': {
      DEPS.ROOT: os.path.join(PATHS.DEPS_ROOT, 'bite'),
      DEPS.URL: 'http://code.google.com/p/bite-project',
      DEPS.COMMAND: [git, 'clone']
    }
  }
  if not DEPS.VerifyAndDownload(deps, verbose):
    print 'Build failed ... exiting.'
    exit()
  if verbose:
    print ''

  if args[FLAGS.DEPS]: # Stop here if deps flag is given; only download deps.
    exit()

  # Check to see if install/uninstall commands are present.
  tests_dst = os.path.join(PATHS.OUTPUT_ROOT, ie7.IE7_ROOT)
  if args[ie7.INSTALL] is not None:
    run_ie7.Install(args[ie7.INSTALL], tests_dst)
    exit()
  elif args[ie7.UNINSTALL] is not None:
    run_ie7.Uninstall(args[ie7.UNINSTALL], tests_dst)
    exit()

  # Remove outputs, so they will be created again.
  if os.path.exists(PATHS.OUTPUT_ROOT):
    shutil.rmtree(PATHS.OUTPUT_ROOT)
  os.mkdir(PATHS.OUTPUT_ROOT)

  # Generate IE7+ tests
  gen_ie7.GenIE7(src_root=ie7.IE7_ROOT, dst_root=tests_dst)

  # Create Test Extension bundle
  # Output will be
  #     output/test_extension
  test_extension_bundle_src = 'test_extension'
  test_extension_bundle_dst = os.path.join(PATHS.GENFILES_ROOT,
                                           'test_extension')

  print 'Creating Chrome test extension bundle.'
  if os.path.exists(test_extension_bundle_dst):
    shutil.rmtree(test_extension_bundle_dst)
  shutil.copytree(test_extension_bundle_src, test_extension_bundle_dst)
  test_extension_bundle_dst = os.path.join(PATHS.OUTPUT_ROOT, 'test_extension')
  shutil.copytree(test_extension_bundle_src, test_extension_bundle_dst)

  # Generate for Firefox3.6+.
  # The output will be
  #     output/test_extension_mimic_ff36.xpi
  test_extension_bundle_dst = os.path.join(PATHS.GENFILES_ROOT,
                                           'test_extension')
  alias = 'test_extension'
  id = 'test_extension2312321@mimic.com'
  creator = 'jasonstredwick@google.com (Jason Stredwick)'
  gen_firefox3_6.GenFirefox3_6('firefox3_6',
                               test_extension_bundle_dst,
                               PATHS.GENFILES_ROOT,
                               PATHS.OUTPUT_ROOT,
                               deps, verbose,
                               alias, id=id, creator=creator,
                               deps_location='')


if __name__ == '__main__':
  Main()
